package com.mugui.base.client.net.bagsend;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import com.mugui.base.util.RequestMethod;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;

import lombok.Getter;
import lombok.Setter;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;


public class HTTPUtil {

    private static HashMap<String, OkHttpClient> map = new HashMap<>();

    /**
     * @param url 服务器
     * @return
     * @auther 木鬼
     */
    public static Object get(String url) {
        return okHttp(RequestMethod.GET, url, null, null);
    }

    /**
     * @param url    服务器
     * @param header header
     * @return
     * @auther 木鬼
     */
    public static Object get(String url, Map<String, String> header) {
        return okHttp(RequestMethod.GET, url, header, null);
    }

    /**
     * @param url 转发服务器
     * @return
     * @auther 木鬼
     */
    public static String post(String url) {
        return okHttp(RequestMethod.POST, url, null, null);
    }

    /**
     * @param url  转发服务器
     * @param body body路径
     * @return
     * @auther 木鬼
     */
    public static String post(String url, String body) {
        return okHttp(RequestMethod.POST, url, null, body);
    }

    /**
     * @param url    转发服务器
     * @param header header
     * @param body   body路径
     * @return
     * @auther 木鬼
     */
    public static String post(String url, Map<String, String> header, String body) {
        return okHttp(RequestMethod.POST, url, header, body);
    }

    /**
     * @param url    转发服务器
     * @param header header
     * @param file   file路径
     * @return
     * @auther 木鬼
     */
    public static String post(String url, Map<String, String> header, JSONObject object, File[] file) {
        return okHttpFile(url, header, object, file);
    }


    @Setter
    @Getter
    private static long outTime = 15;


    public static String okHttp(RequestMethod method, String url, Map<String, String> headler, String body) {
        try {
            HttpResponse response = null;
            if (method == RequestMethod.GET) {
                response = HttpRequest.get(url).setMaxRedirectCount(4).headerMap(headler, true).timeout((int) outTime*1000).execute();
            } else if (method == RequestMethod.POST) {
                response = HttpRequest.post(url).body(body).setMaxRedirectCount(4).headerMap(headler, true).timeout((int) outTime*1000).execute();

            }
            if (response!=null&&response.getStatus() == 200) {
                return response.body();
            } else {
                throw new RuntimeException(response.getStatus() + "" + response.body());
            }

        } catch (Exception e) {
            throw new RuntimeException(method + ":" + url + "--" + body, e);
        }
    }

    private static String okHttpFile(String url, Map<String, String> headler, JSONObject object, File[] file) {
        if (file == null || file.length == 0) {
            throw new RuntimeException("File file 不能为空");
        }
        OkHttpClient httpClient = map.get(url);
        if (httpClient == null) {
            synchronized (map) {
                httpClient = map.get(url);
                if (httpClient == null) {
                    httpClient = new OkHttpClient().newBuilder().connectTimeout(outTime, TimeUnit.SECONDS)
                            .readTimeout(outTime, TimeUnit.SECONDS).build();
                    map.put(url, httpClient);
                }
            }
        }
        InputStream inputStream = null;
        ByteArrayOutputStream outputStream = null;
        Response response = null;
        try {
            Request.Builder request = getRequest(url, headler);
            MultipartBody.Builder builder = new MultipartBody.Builder();
            builder.setType(MultipartBody.FORM);
            {
                Iterator<Entry<String, Object>> iterator = object.entrySet().iterator();
                while (iterator.hasNext()) {
                    Entry<String, Object> next = iterator.next();
                    if (next.getValue() != null)
                        builder.addFormDataPart(next.getKey(), next.getValue().toString());
                }
            }
            {

                for (int i = 0; i < file.length; i++) {
					/*builder.addFormDataPart(NetBag.STEALTH_UPLOAD_FILE, file[i].getOriginalFilename(),
							RequestBody.create(MediaType.parse(file[i].getContentType()), item.getStoreLocation()));*/
                }
            }

            response = httpClient.newCall(request.post(builder.build()).build()).execute();
            if (response.code() == 200) {
                inputStream = response.body().byteStream();
                outputStream = new ByteArrayOutputStream();
                byte[] by = new byte[1024];
                int len = -1;
                while ((len = inputStream.read(by)) > -1) {
                    outputStream.write(by, 0, len);
                }
                return outputStream.toString("UTF-8");
            }
            inputStream = response.body().byteStream();
            outputStream = new ByteArrayOutputStream();
            byte[] by = new byte[1024];
            int len = -1;
            while ((len = inputStream.read(by)) > -1) {
                outputStream.write(by, 0, len);
            }
            throw new RuntimeException(response.code() + "" + outputStream.toString("UTF-8"));
        } catch (Exception e) {
            throw new RuntimeException("okHttpFile :" + url + "--", e);
        } finally {
            try {
                if (outputStream != null)
                    outputStream.close();
                if (inputStream != null)
                    inputStream.close();
                if (response != null)
                    response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    private static Request.Builder getRequest(String url, Map<String, String> headler) {
        Request.Builder builder = new Request.Builder().url(url);
        if (headler != null) {
            Iterator<Entry<String, String>> iterator = headler.entrySet().iterator();

            while (iterator.hasNext()) {
                Entry<String, String> next = iterator.next();
                builder = builder.addHeader(next.getKey().trim(), next.getValue().trim());
            }
        }
        return builder;
    }

}
